package net.zui.comp;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.image.BufferStrategy;
import java.util.Timer;
import java.util.TimerTask;

import net.zui.Option;
import net.zui.action.ActionDispather;
import net.zui.action.InnerWindowAction;
import net.zui.action.WindowKeyAction;
import net.zui.action.WindowMouseAction;
import net.zui.action.ZKeyAction;
import net.zui.action.ZMouseAction;
import net.zui.action.ZWindowAction;
import net.zui.entity.ZBaseManager;
import net.zui.inter.IGroup;
import net.zui.util.UComm;

public abstract class ZBaseFrame extends Frame implements IGroup{
	private static final long serialVersionUID = 1L;
	protected boolean change=false;
	protected int innerX,innerY,innerWidth,innerHeight;
	protected String id;
	private volatile boolean first=true;
	private Timer time;
	private Canvas canvas;

	private BufferStrategy bs;
	
	protected ZKeyAction outerKey;
	protected ZMouseAction outerMouse;
	protected ZWindowAction outerWindow;
	
	private InnerWindowAction innerWindow;
	@SuppressWarnings("unused")
	private WindowMouseAction innerMouse;
	@SuppressWarnings("unused")
	private WindowKeyAction innerKey;
	
	protected ZBaseManager manager=new ZBaseManager();
	protected ActionDispather dispather=new ActionDispather(this);

	public ZBaseFrame(String id) throws HeadlessException {
		this(id,Option.title);
	}
	
	public ZBaseFrame(String id,String title) throws HeadlessException {
		super(title==null?Option.title:title);
		if(id==null || id.isEmpty()) {
			id=ZBaseManager.getId(this.getClass());
			UComm.info(this.getClass(),"BaseFrame`s id is null or empty, set new id is:",id);
		}else {
			this.id=id;
		}
		setLayout(null);
		setResizable(false);
		innerWindow=new InnerWindowAction(this);
	}
	/**
	 * 初始化组件以及窗口, 应该只被调用一次
	 */
	protected abstract void init();
	/**
	 * 初始化完成后, 回调事件
	 */
	protected void afterInit() {};
	
	@Override
	public void setVisible(boolean b) {
		super.setVisible(b);
		if(!first)return;
		first=false;
		manager.setWidth(innerWidth);
		manager.setHeight(innerHeight);
		init();
		selfInit();
		afterInit();
	}
	
	private final void selfInit() {
		Insets insets = getInsets();
		//UComm.info(ZBaseFrame.class, innerX,",",innerY,",",innerWidth,",",innerHeight,",");
		canvas=new Canvas();
		canvas.setSize(innerWidth, innerHeight);
		canvas.setLocation(insets.left, insets.top);
		canvas.setIgnoreRepaint(true);
		this.add(canvas);
		canvas.requestFocus();
		canvas.createBufferStrategy(2);
		canvas.setBackground(Option.getBackColor());
		bs=canvas.getBufferStrategy();
		time=new Timer();
		time.schedule(new TimerTask() {
			Graphics2D g=null;
			@Override
			public void run() {
				g=(Graphics2D) bs.getDrawGraphics();
				g.clearRect(0, 0, innerWidth, innerHeight);
				g.setRenderingHints(Option.renderingHints);
				for(ZBase base:manager.bases()) {
					base.update(g);
				}
				g.dispose();
				bs.show();
			}
		},100,100);	
		
		innerWindow=new InnerWindowAction(this);
		innerMouse=new WindowMouseAction(this);
		innerKey=new WindowKeyAction(this);
	}

	public String getId() {
		return id;
	}
	
	@Override
	public ZBaseFrame getTop() {
		return this;
	}
	
	@Override
	public void setBackground(Color bgColor) {
		super.setBackground(bgColor);
		if(canvas!=null)canvas.setBackground(bgColor);
	}
	
	@Override
	public String toString() {
		return UComm.arrToStr("{BaseFrame}id=",id,";x,y,width,height=",getX(),",",getY(),",",getWidth(),",",getHeight());
	}

	public int getInnerX() {
		return innerX;
	}

	public void setInnerX(int innerX) {
		this.innerX = innerX;
	}

	public int getInnerY() {
		return innerY;
	}

	public void setInnerY(int innerY) {
		this.innerY = innerY;
	}

	public int getInnerWidth() {
		return innerWidth;
	}

	public void setInnerWidth(int innerWidth) {
		this.innerWidth = innerWidth;
	}

	public int getInnerHeight() {
		return innerHeight;
	}

	public void setInnerHeight(int innerHeight) {
		this.innerHeight = innerHeight;
	}

	public ZKeyAction getOuterKey() {
		return outerKey;
	}

	public void setOuterKey(ZKeyAction outerKey) {
		this.outerKey = outerKey;
	}

	public ZMouseAction getOuterMouse() {
		return outerMouse;
	}

	public void setOuterMouse(ZMouseAction outerMouse) {
		this.outerMouse = outerMouse;
	}

	public ZWindowAction getWindowAction() {
		return outerWindow;
	}

	public void setWindowAction(ZWindowAction windowAction) {
		this.outerWindow = windowAction;
	}

	public ZBaseManager getManager() {
		return manager;
	}
	
	public ActionDispather getActionDispather() {
		return dispather;
	}

	public ZWindowAction getInnerWindow() {
		return innerWindow;
	}
	
	public Canvas getCanvas() {
		return canvas;
	}
	
	@Override
	public void setSize(int width, int height) {
		super.setSize(width, height);
		Insets insets = getInsets();
		innerWidth=getWidth()-insets.left-insets.right;
		innerHeight=getHeight()-insets.top-insets.bottom;
	}
}
